#ifndef _DEBUGGER_H_
#define _DEBUGGER_H_

#include "./basic_define.h"

//#define ALLOW_DEBUGS
#define ALLOW_EXCEPT

#include<map>

//! Namespace for functions and debugging techniques
/*!
	Functions that make debugs easier and creates default pattern
*/
namespace Debug {

	using namespace Define;

	//! Default function/method debug
	/*!
		Function for debugging functions and methods.
		All information for a simple default debug is allowed.
		
		\param method_name The name of the function being called.
		\param instance_name The name of the instance calling it (often used for classes).
		\param address Pointer to the object.
		\param size Bytes used for this object.
		\param ident Individual identifier for the object.
		
		\sa Identifiable::Identifiable()
		
		\code
			ClassName(){
				// often used inside an #ifdef DEBUG_LABEL
				debug_function_info( "Constructor: ", "ClassName", &( *this ), sizeof( *this ) );
				// ... // extra debugs, #endif
				// ... // starting up the instance
			};
		\endcode
		\code
			ClassName():Idb(){
				debug_function_info( "Constructor: ", "ClassName", &( *this ), sizeof( *this ), id );
				// ... // extra debugs
				// ... // starting up the instance
			};
		\endcode
	*/
	void debug_function_info(
		const string &method_name, const string &instance_name,
		int address, const usint &size, const usint &ident = 0 );

	inline void debug_small(
		const string &method_name, const string &instance_name,
		int address, const usint &size){
			
		cout << ">Debug " << method_name << " : " << instance_name << " < " << address << "," << size << " >" << endl;
	};

/*	inline void debug_break_point (void){
		static unsigned int pn = 0;
		printf ("%d\n", pn++);
	}
*/

	class Identifiable {
	protected:
	public:
		
		virtual ~Identifiable(){};

		// --- Identifiable ---

		virtual bool operator == ( const Identifiable &obj ) const = 0;

		inline bool operator != ( const Identifiable &obj ) const { return ! ( (*this) == obj ); };
	};

	/*! Allows writing with less characters */
	typedef Identifiable Idb;

	class Classificable {
	protected:
	public:
		
		virtual ~Classificable() {};

		// --- Classificable ---

		static string ClassName() {
			return "Classificable";
		};

		virtual string className() const = 0;

	};

	/*! Allows writing with less characters */
	typedef Classificable Clsb;

};

#endif
